home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Dev
/
GNU-SMALLTALK.lha
/
Float.st
< prev
next >
Wrap
Text File
|
1992-02-15
|
6KB
|
233 lines
"======================================================================
|
| Float Method Definitions
|
======================================================================"
"======================================================================
|
| Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 1, or (at your option) any later version.
|
| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
| details.
|
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file COPYING. If not, write to the Free Software
| Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
======================================================================"
"
| Change Log
| ============================================================================
| Author Date Change
| sbb 24 Mar 91 Fixed up floating point printing to take account of
| the number of digits printed in the integer part when
| printing the fractional part.
|
| sbb 16 Mar 91 Class creation now separate statement.
|
| sbb 20 Sep 90 Fixed storeOn: to not be recursive.
|
| sbyrne 15 Apr 90 Added asFloat...I could have sworn this was already
| here...must have been lost in an edit.
|
| sbyrne 25 Apr 89 created.
|
"
Number variableWordSubclass: #Float "not really a variable class"
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: nil
!
Float comment:
'My instances represent floating point numbers that have 64 bits of
precision (well, less than that in precision; they are precisely the same
as C''s "double" datatype). Besides the standard numerical operations,
I provide transcendental operations too.' !
!Float class methodsFor: 'basic'!
pi
"Returns the value of pi"
^3.14159265358979323846264338327950288
!!
!Float methodsFor: 'arithmetic'!
// aNumber
"Return the integer quotient of dividing the receiver by aNumber with
truncation towards negative infinity."
^(self / aNumber) floor
!
\\ aNumber
"Return the remainder of dividing the receiver by aNumber with
truncation towards negative infinity."
^(self - (self // aNumber * aNumber)) floor
!
integerPart
^self - self fractionPart
!!
!Float methodsFor: 'coercing methods'!
coerce: aNumber
^aNumber asFloat
!
generality
^4
!
asFloat
"Just defined for completeness."
^self
!
hash
"Returns the hash value for the receiver (a Float). If it's representable
as an integer, we use that value, since it's likely to be much more random,
but if not, we use the exponent. Another approach that may be used in
the future is to scale the number so that it's within the integer range if
it's not normally and then return the integer part"
| expt |
expt _ self exponent.
expt >= 0 & (expt < 31)
ifTrue: [ ^self truncated ]
ifFalse: [ ^expt ]
!!
!Float methodsFor: 'copying'!
shallowCopy
^self
!
deepCopy
^self
!!
!Float methodsFor: 'printing'!
printOn: aStream
| num exp |
(self exponent between: -50 and: 49)
ifTrue: [ self printFloatOn: aStream ]
ifFalse: [ exp _ 0.
num _ self.
num abs < 1.0
ifTrue: [ [ num abs < 1.0 ] whileTrue:
[ num _ num * 10.0.
exp _ exp - 1 ] ]
ifFalse: [ [num abs >= 10.0] whileTrue:
[ num _ num / 10.0.
exp _ exp + 1 ] ].
num printFloatOn: aStream.
aStream nextPut: $e.
exp printOn: aStream ].
!!
!Float methodsFor: 'storing'!
storeOn: aStream
self printOn: aStream
!!
!Float methodsFor: 'private'!
printFloatOn: aStream
| num str intDigits |
num _ self.
num < 0.0 ifTrue:
[ aStream nextPut: $-.
num _ num negated. ].
intDigits _ num printIntegerPartOn: aStream.
aStream nextPut: $..
num printFracPartOn: aStream digitsPrinted: intDigits.
!
printIntegerPartOn: aStream
| num digitString numDigits |
num _ self integerPart.
(digitString _ num revDigitsBase: 10.0) reverseDo:
[ :char | aStream nextPut: char ].
numDigits _ digitString size.
$0 = (digitString at: 1) "we've been forced to emit a 0; doesn't count"
ifTrue: [ numDigits _ numDigits - 1 ].
^numDigits
!
printFracPartOn: aStream digitsPrinted: numDigits
| num count zeroCount digit digitLimit |
num _ self fractionPart.
num = 0.0 ifTrue: [ ^aStream nextPut: $0 ].
zeroCount _ count _ 0.
" produce the digits, up to a maximum of 15, suppressing trailing
zeros (ln(2^52)/ln(10)) "
digitLimit _ 15 - numDigits.
[ (num ~= 0.0) & (count < digitLimit) ] whileTrue:
[ num _ num * 10.0.
digit _ num floor.
digit = 0 "for trailing zero suppression"
ifTrue: [ zeroCount _ zeroCount + 1 ]
ifFalse: [ aStream next: zeroCount put: $0.
aStream nextPut: (Character digitValue: digit).
zeroCount _ 0 ].
num _ num fractionPart.
count _ count + 1 ].
zeroCount = digitLimit ifTrue: [ aStream nextPut: $0 ]
!
"AARRGGHH! Why can't I share this code with integer? Grrr...."
revDigitsBase: b
| str num digit |
str _ WriteStream on: (String new: 10).
self = 0.0
ifTrue: [ str nextPut: $0 ]
ifFalse: [
num _ self.
[ num = 0.0 ] whileFalse:
[ "stdout nextPutAll: '------------'; nl.
num basicPrint.
(num/b) basicPrint.
(num/b) fractionPart basicPrint.
((num/b) fractionPart * b) basicPrint.
((num/b) fractionPart * b) rounded basicPrint."
digit _ ((num / b) fractionPart * b) rounded.
str nextPut: (Character digitValue: digit).
num _ (num / b) integerPart ] ].
^str contents
! !